package xx.shiro.config;

import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.util.StringUtils;
import xx.shiro.entity.SysPermissions;
import xx.shiro.entity.SysRole;
import xx.shiro.entity.SysUser;
import xx.shiro.service.LoginService;


import javax.annotation.Resource;
import java.security.Permissions;

/**
 * 自定义Realm
 * 查询用户的角色和权限信息并保存到权限管理器
 */
public class CustomerRealm extends AuthorizingRealm {

    @Resource
    private LoginService loginService;

    /**
     * 权限配置类
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取登录用户名
        String name = (String) principalCollection.getPrimaryPrincipal();
        //查询用户名称
        SysUser user = loginService.queryUserInfoByUserName(name);
        //添加角色和权限
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        for (SysRole role : user.getSysRoleList()) {
            //添加角色
            simpleAuthorizationInfo.addRole(role.getName());
            //添加权限
            for (SysPermissions permissions : user.getPermissionsSet()) {
                simpleAuthorizationInfo.addStringPermission(permissions.getName());
            }
        }
        return simpleAuthorizationInfo;
    }

    /**
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        if (StringUtils.isEmpty(authenticationToken.getPrincipal())) {
            return null;
        }
        //获取用户信息
        UsernamePasswordToken userToken = (UsernamePasswordToken)authenticationToken;
        System.out.println("-------------- authenticationToken.getCredentials() --------------"+authenticationToken.getCredentials());
        SysUser user = loginService.queryUserInfoByUserName(userToken.getUsername());
        if (user == null) {
            //这里返回后会报出对应异常
            throw new UnknownAccountException("用户不存在");
        } else {
            //这里验证authenticationToken和simpleAuthenticationInfo的信息
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
            simpleAuthenticationInfo.setCredentialsSalt(ByteSource.Util.bytes("YX")); //加盐
            return simpleAuthenticationInfo;
        }
    }

    //2.判断密码
    //第一个字段是加密算法
    //第二个字段是user.getPassword()，注意这里是指从数据库中获取的password。
    //第三个字段是盐值
    //第四个字段是realm，即当前realm的名称。
    //从这里传入的password（这里是从数据库获取的）和token（filter中登录时生成的）中的password做对比，如果相同就允许登录，不相同就抛出IncorrectCredentialsException异常。
    // 将账户名,密码,盐值,getName()实例化到SimpleAuthenticationInfo中交给Shiro来管理
    //return new SimpleAuthenticationInfo(principal, credentials, byteSource, realmName);
}
